package com.example.boot.annotation;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class DesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer {
    private DesensitizeType desensitizeType;

    /**
     * 执行脱敏序列化
     * @param value 原始字段值
     * @param gen JSON 生成器
     * @param provider 序列化提供器
     */
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        // 根据脱敏类型处理数据
        switch (desensitizeType) {
            case PHONE:
                gen.writeString(desensitizePhone(value));
                break;
            case ID_CARD:
                gen.writeString(desensitizeIdCard(value));
                break;
            case EMAIL:
                gen.writeString(desensitizeEmail(value));
                break;
            default:
                gen.writeString(value);
        }
    }

    /**
     * 创建上下文相关的序列化器实例
     * @param prov 序列化提供器（包含 ObjectMapper 配置）
     * @param property 当前序列化的字段属性
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        // 处理字段属性为空的情况（如 Map 中的值）
        if (property == null) return prov.findNullValueSerializer(null);

        // 获取字段上的 @Desensitize 注解
        Desensitize annotation = property.getAnnotation(Desensitize.class);
        // 检查字段是否标记了 @Desensitize 注解，且字段类型为 String
        if (annotation != null && String.class.equals(property.getType().getRawClass())) {
            DesensitizeSerializer serializer = new DesensitizeSerializer();
            serializer.desensitizeType = annotation.value();
            return serializer;
        }

        // 默认返回 String 类型的序列化器
        return prov.findValueSerializer(property.getType(), property);
    }

    // 手机号脱敏：138****1234
    private String desensitizePhone(String phone) {
        if (phone.length() != 11) return phone; // 简单校验
        return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    // 身份证脱敏：420***********1234
    private String desensitizeIdCard(String idCard) {
        if (idCard.length() < 18) return idCard;
        return idCard.replaceAll("(\\d{3})\\d{12}(\\d{3})", "$1************$2");
    }

    // 邮箱脱敏：abc***@example.com
    private String desensitizeEmail(String email) {
        int atIndex = email.indexOf("@");
        if (atIndex <= 3) return email;
        String prefix = email.substring(0, 3);
        return prefix + "***" + email.substring(atIndex);
    }
}